package cc.rengu.redp.bizimpl.upmp.service.impl;

import cc.rengu.igas.bomp.facade.BompManualAdjustAcctService;
import cc.rengu.igas.bomp.facade.request.ManualAccoutingStatusQueryRequest;
import cc.rengu.igas.bomp.facade.request.ManualPaymentRequest;
import cc.rengu.igas.bomp.facade.response.ManualAccoutingStatusQueryResponse;
import cc.rengu.igas.bomp.facade.response.ManualPaymentResponse;
import cc.rengu.igas.bomp.facade.result.Result;
import cc.rengu.redp.bizimpl.enums.*;
import cc.rengu.redp.bizimpl.upmp.common.BusinessContainer;
import cc.rengu.redp.bizimpl.upmp.domain.BManualAcctInfo;
import cc.rengu.redp.bizimpl.upmp.dao.BManualAcctInfoMapper;
import cc.rengu.redp.bizimpl.upmp.domain.BizTmp;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpPrivilegeCheck;
import cc.rengu.redp.bizimpl.upmp.service.*;
import cc.rengu.redp.bizimpl.upmp.vo.OperationResult;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.Common;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.bizimpl.utils.DateUtils;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.common.utils.SortUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Map;

/**
 * @author lizk
 */
@Service
@DS("upmp")
public class BManualAcctInfoServiceImpl extends ServiceImpl<BManualAcctInfoMapper, BManualAcctInfo> implements IBManualAcctInfoService {

    @Autowired
    private IUpmpSysParamService upmpSysParamService;
    @Autowired
    private IUpmpPrivilegeCheckService authPrivilegeCheckService;
    @Autowired
    private IBizTmpService bizTmpService;
    @Autowired
    private IBizHisService bizHisService;
    @Autowired
    private IUpmpSysSeqService sysSeqService;
    @Autowired
    private IUpmpBMchntBaseInfoService bMchntBaseInfoService;
    @Autowired(required = false)
    private BompManualAdjustAcctService bompManualAdjustAcctService;


    private long oprMenuId = 1;
    private String oprMenuName = "清分清算管理:手工挂账管理";
    private long chkMenuId = 2;
    private String chkMenuName = "清分清算管理:手工挂账管理";
    private String webNextUrl = "/admin/upmp/bManualAcctInfo";

    @Override
    public IPage<BManualAcctInfo> findByPage(QueryRequest queryRequest, BManualAcctInfo manualAcctInfo) {
        try {
            //获取当前登录人信息
            UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
            String instId = manualAcctInfo.getInstId();
            if (Common.isBlank(instId)) {
                instId = user.getInstId();
            }
            LambdaQueryWrapper<BManualAcctInfo> queryWrapper = new LambdaQueryWrapper<>();
            if (!StringUtils.isEmpty(instId)) {
                queryWrapper.eq(BManualAcctInfo::getInstId, instId);
            }
            if (!StringUtils.isEmpty(manualAcctInfo.getAdjustDate())) {
                queryWrapper.eq(BManualAcctInfo::getAdjustDate, manualAcctInfo.getAdjustDate());
            }

            Page<BManualAcctInfo> page = new Page<>();

            SortUtil.handlePageSort(queryRequest, page, true);

            //设置模型数量和商户名称
            Page<BManualAcctInfo> infoPage = this.page(page, queryWrapper);

            return infoPage;
        } catch (Exception e) {
            log.error("获取手工挂账信息失败", e);
            return null;
        }
    }

    @Override
    public OperationResult saveData(BManualAcctInfo entity) throws RedpException {
        String flag = entity.getOptFlag();
        Map<String, Object> result = com.google.common.collect.Maps.newHashMap();
        String lastUpddt = DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
        String adjustDate = DateUtils.formatDate(new Date(), "yyyyMMdd");
        String adjustTime = DateUtils.formatDate(new Date(), "HHmmss");
        //获取当前登录人信息
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);

        if (PageOptFlagEnum.OPT_FLAG_ADD.getType().equals(flag)) {

            entity.setAdjustDate(adjustDate);
            entity.setAdjustTime(adjustTime);
            entity.setCreateTime(lastUpddt);
            entity.setAcctStatus("00");

            UpmpPrivilegeCheck privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(entity.getInstId(), "manualAcctInfo:add");

            if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {

                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_CHECKING.getType());
                this.save(entity);

                bizTmpService.saveBizTmp(entity, user, user.getId(), BizOprEnum.OPR_ADD.getType(), lastUpddt
                        , String.valueOf(oprMenuId), oprMenuName, BizDataStatusEnum.STATUS_DRAFT.getType(), entity.getAuditStatus(), String.valueOf(entity.getId()), webNextUrl, null, null, null);
                result.put("id", entity.getId());
                result.put("status", "false");
            } else {
                entity.setLastAuditTime(lastUpddt);
                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_PASS.getType());
                this.save(entity);
                bizHisService.saveBizHisNew(entity, new BManualAcctInfo(), user, user.getId(), BizOprEnum.OPR_ADD.getType(), lastUpddt
                        , String.valueOf(oprMenuId), oprMenuName, String.valueOf(entity.getId()), null, null, null);
                result.put("id", entity.getId());
                result.put("status", "true");
                result.put("entity", entity);
            }
        } else if (PageOptFlagEnum.OPT_FLAG_UPDATE.getType().equals(flag)) {

            String id = entity.getId();
            if (Common.isBlank(id)) {
                log.error("请求参数(id)异常!");
                return OperationResult.buildFailureResult("请求参数(id)异常!", result);
            }
            UpmpPrivilegeCheck privilegeCheck = authPrivilegeCheckService.getPrivilegeCheckByPrivilegeCode(user.getInstId(), "manualAcctInfo:edit");
            BManualAcctInfo bmanualacctinfo = baseMapper.selectById(id);
            BManualAcctInfo bmanualacctinfonew = new BManualAcctInfo();
            BeanUtils.copyProperties(entity, bmanualacctinfonew);

            entity.setLastOprId(user.getId());
            entity.setLastUpdateTime(lastUpddt);
            if (null != privilegeCheck && BusinessContainer.YES.equals(privilegeCheck.getChecked())) {

                bmanualacctinfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_CHECKING.getType());
                this.saveOrUpdate(bmanualacctinfo);

                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_CHECKING.getType());
                BeanUtils.copyProperties(entity, bmanualacctinfo);
                //检查临时表是否有数据，如果没用则新增
                bizTmpService.saveBizTmp(bmanualacctinfo, user, user.getId(), BizOprEnum.OPR_UPDATE.getType(), lastUpddt
                        , String.valueOf(oprMenuId), oprMenuName, BizDataStatusEnum.STATUS_DRAFT.getType(), bmanualacctinfo.getAuditStatus(), String.valueOf(bmanualacctinfo.getId()), webNextUrl, null, null, null);
                result.put("id", bmanualacctinfo.getId());
                result.put("status", "false");
            } else {

                entity.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());

                BeanUtils.copyProperties(entity, bmanualacctinfo);
                this.saveOrUpdate(bmanualacctinfo);

                //历史表新增
                bizHisService.saveBizHisNew(bmanualacctinfonew, bmanualacctinfo, user, user.getId(), BizOprEnum.OPR_UPDATE.getType(), lastUpddt
                        , String.valueOf(oprMenuId), oprMenuName, String.valueOf(bmanualacctinfo.getId()), null, null, null);
                result.put("status", "true");
                result.put("entity", bmanualacctinfo);
                result.put("id", entity.getId());
            }
        } else if (PageOptFlagEnum.OPT_FLAG_CHECK.getType().equals(flag)) {

            String id = entity.getId();
            if (Common.isBlank(id)) {
                log.error("请求参数(id)异常!");
                return OperationResult.buildFailureResult("请求参数(id)异常!", result);
            }

            //获取临时表数据并转换成实体对象
            BizTmp tmp = bizTmpService.getBizTmpDetail(id);
            if (Common.isBlank(tmp)) {
                log.error("根据id没有找到指定临时表数据！");
                return OperationResult.buildFailureResult("根据id没有找到指定临时表数据！", result);
            }
            String bizdata = "";
            if (null != tmp.getBizData1()) {
                bizdata += tmp.getBizData1();
            }
            if (null != tmp.getBizData2()) {
                bizdata += tmp.getBizData2();
            }
            if (null != tmp.getBizData3()) {
                bizdata += tmp.getBizData3();
            }
            //临时表数据
            BManualAcctInfo bmanualacctinfoNew = JSON.parseObject(bizdata, BManualAcctInfo.class);
            //正式表数据
            BManualAcctInfo bmanualacctinfo = baseMapper.selectById(id);
            //备份正式表数据
            BManualAcctInfo bmanualacctinfoOld = new BManualAcctInfo();
            BeanUtils.copyProperties(bmanualacctinfo, bmanualacctinfoOld);

            if (Common.isBlank(bmanualacctinfo) && !BizOprEnum.OPR_ADD.equals(tmp.getBizOpr())) {
                log.error("根据id没有找到指定数据！");
                return OperationResult.buildFailureResult("根据id没有找到指定数据！", result);
            }

            String opt = entity.getOpt();
            if (Common.isBlank(opt)) {
                log.error("请求参数(opt)异常!");
                return OperationResult.buildFailureResult("请求参数(opt)异常!", result);
            }

            if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                // 审批通过将临时表数据更新到正式表
                BeanUtils.copyProperties(bmanualacctinfoNew, bmanualacctinfo);
            } else {
                String approvalRefuseReason = entity.getAuditRefuseReason();
                bmanualacctinfo.setAuditRefuseReason(approvalRefuseReason);
            }
            String bizOpr = "";
            if (BizDataAuditStatusEnum.AUDIT_STATUS_ADD_CHECKING.getType().equals(bmanualacctinfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    bmanualacctinfo.setLastAuditId(user.getId());
                    bmanualacctinfo.setLastAuditTime(lastUpddt);
                    bmanualacctinfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_PASS.getType());
                    result.put("status", "true");
                } else {
                    bmanualacctinfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_ADD_REJECT.getType());
                    result.put("status", "false");
                }
                bizOpr = BizOprEnum.OPR_ADD.getType();
            } else if (BizDataAuditStatusEnum.AUDIT_STATUS_UPD_CHECKING.getType().equals(bmanualacctinfo.getAuditStatus())) {
                if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                    //TODO  审核通过后调用手工调账接口
                    bmanualacctinfo.setLastAuditId(user.getId());
                    bmanualacctinfo.setLastAuditTime(lastUpddt);
                    bmanualacctinfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_PASS.getType());
                    result.put("status", "true");
                } else {
                    bmanualacctinfo.setAuditStatus(BizDataAuditStatusEnum.AUDIT_STATUS_UPD_REJECT.getType());
                    result.put("status", "false");
                }
                bizOpr = BizOprEnum.OPR_UPDATE.getType();
            }
            this.saveOrUpdate(bmanualacctinfo);
            if (PageOptFlagEnum.OPT_FLAG_PASS.getType().equals(opt)) {
                //审批通过将正式表更新到历史表
                bizHisService.saveBizHisNew(bmanualacctinfo, bmanualacctinfoOld, user, user.getId(), bizOpr, lastUpddt, String.valueOf(chkMenuId), oprMenuName, String.valueOf(bmanualacctinfo.getId()), null, null, null);
            }
            // 修改临时表的审核状态等字段
            bizTmpService.saveBizTmp(bmanualacctinfo, user, user.getId(), bizOpr, lastUpddt, String.valueOf(chkMenuId), oprMenuName, "01", bmanualacctinfo.getAuditStatus(), String.valueOf(bmanualacctinfo.getId()), webNextUrl, null, null, null);
            result.put("entity", bmanualacctinfo);
        }

        return OperationResult.buildSuccessResult("数据保存处理完成", result);
    }

    @Override
    public void manualPayment(BompManualAdjustAcctService bompManualAdjustAcctService, BManualAcctInfo entity) {
        ManualPaymentRequest req = new ManualPaymentRequest();
        //获取当前登录人信息
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        String traceNo = bMchntBaseInfoService.genMerOrder(user.getInstId());
        req.setHeader(CommonUtils.packageBompHeader(traceNo, BompTxnNumEnum.manualPayment.getType(), entity.getInstId(), null));
        req.setPayeeAcctNo(entity.getPayeeAcctInfo());
        req.setPayerAcctNo(entity.getPayerAcctInfo());
        req.setAdjustAmt(entity.getAdjustAmt());
        req.setAcctUnionKey(entity.getId());
        req.setUserId(user.getId());
        log.error("手工挂账" + BompTxnNumEnum.manualPayment.getDesc() + "请求报文：" + JSON.toJSONString(req));
        try {
            Result<ManualPaymentResponse> response = bompManualAdjustAcctService.manualPayment(req);
            log.error("手工挂账" + BompTxnNumEnum.manualPayment.getDesc() + "返回报文：" + JSON.toJSONString(response));
            ManualPaymentResponse result = response.getResult();
            if (response.isSuccess()) {
                ManualPaymentResponse resp = response.getResult();

                if (BusinessContainer.BSPS_SUCCESS.equals(resp.getRespCode())) {
                    log.error("手工挂账" + BompTxnNumEnum.manualPayment.getDesc() + "交易成功");
                } else {
                    log.error("手工挂账" + BompTxnNumEnum.manualPayment.getDesc() + "交易失败");
                }
            } else {
                log.error("手工挂账:" + BompTxnNumEnum.manualPayment.getDesc() + "交易没有获得返回信息");
            }
        } catch (Exception e) {
            log.error("手工挂账：，" + BompTxnNumEnum.manualAdjustment.getDesc() + "交易出现异常，异常信息：" + e.getMessage(), e);
        }
    }

    @Override
    public Map<String, String> manualAccoutingStatusQuery(BManualAcctInfo entity, BompManualAdjustAcctService bompManualAdjustAcctService) throws RedpException {
        String id = entity.getId();
        //获取当前登录人信息
        UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
        if (Common.isBlank(id)) {
            log.error("请求参数(挂账/调账唯一标识)异常!");
            throw new RedpException("请求参数(挂账/调账唯一标识)异常！");
        }

        String oprType = entity.getOprType();
        String instId = entity.getInstId();
        String traceNo = bMchntBaseInfoService.genMerOrder(user.getInstId());
        ManualAccoutingStatusQueryRequest req = new ManualAccoutingStatusQueryRequest();
        req.setHeader(CommonUtils.packageBompHeader(traceNo, BompTxnNumEnum.manualAccoutingStatusQuery.getType(), instId, null));
        req.setUserId(user.getId());
        req.setAcctOprType(oprType);
        req.setAcctUnionKey(id);
        Map<String, String> result = com.google.common.collect.Maps.newHashMap();
        try {
            log.error("手工调账或挂账状态查询" + BompTxnNumEnum.manualAccoutingStatusQuery.getDesc() + "交易请求报文：" + JSON.toJSONString(req));
            Result<ManualAccoutingStatusQueryResponse> response = bompManualAdjustAcctService.manualAccoutingStatusQuery(req);
            log.error("手工调账或挂账状态查询" + BompTxnNumEnum.manualAccoutingStatusQuery.getDesc() + "交易返回报文：" + JSON.toJSONString(response));
            if (response.isSuccess()) {
                ManualAccoutingStatusQueryResponse resp = response.getResult();
                if (BusinessContainer.BSPS_SUCCESS.equals(resp.getRespCode())) {
                    log.error("手工调账或挂账状态查询" + BompTxnNumEnum.manualAccoutingStatusQuery.getDesc() + "交易成功");
                    result.put("AcctStatus", resp.getAcctStatus());
                    result.put("FailureReason", resp.getFailureReason());
                    result.put("AcctDate", resp.getAcctDate());
                    result.put("AcctSeqNum", resp.getAcctSeqNum());
                    return result;
                } else {
                    log.error("手工调账或挂账状态查询" + BompTxnNumEnum.manualAccoutingStatusQuery.getDesc() + "交易失败");
                    throw new RedpException("手工调账或挂账状态查询交易失败！");
                }
            } else {
                log.error("手工调账或挂账状态查询" + BompTxnNumEnum.manualAccoutingStatusQuery.getDesc() + "交易没有获得返回信息");
                throw new RedpException("手工调账或挂账状态查询交易没有获得返回信息！");
            }
        } catch (Exception e) {
            log.error("手工调账或挂账状态查询" + BompTxnNumEnum.manualAccoutingStatusQuery.getDesc() + "交易出现异常，异常信息：" + e.getMessage(), e);
            throw new RedpException("手工调账或挂账状态查询交易出现异常！");
        }
    }
}
